<?php

require_rewrite(SYSTEM_PATH . 'config/mssql.config.php');
require_rewrite(SYSTEM_PATH . 'lib/DB_Exception.php');

class mssql_connect {

    public function __construct() {
        
    }

    public function __destruct() {
        
    }

    static public function get($master = false) {
        if ($master) {
            $_con = MSconfig::$master_con[0];
        } else {
            if (isset(MSconfig::$rand_num) && MSconfig::$rand_num > 0) {
                $rand = mt_rand(1, MSconfig::$rand_num);
                if (($rand % MSconfig::$rand_num) == 0) {
                    $_con = MSconfig::$master_con[0];
                } else {
                    $_con = MSconfig::$ms_con[self::_rand()];
                }
            } else {
                $_con = MSconfig::$ms_con[self::_rand()];
            }
        }
        return new mssql_db($_con, $pconnect = false, $master);
    }

    private static function _rand() {
        return 0;
//		$num = count(MSconfig::$ms_con);
//		return  mt_rand(0,($num-1) );
    }

}

/**
 * mssql 
 * 
 */
class mssql_db {

    private $dbhost;
    private $dbuser;
    private $dbpwd;
    private $dbname;
    private $pconnect;
    private static $_dbname;
    private static $_handle;
    private static $_master_dbname;
    private static $_master_handle;
    public $insertid;
    private $t_handle;
    private $_sp_msg; //错误信息

    /**
     * 构造函数
     * array(
      'mssql_db_host'=>'10.0.1.200',
      'mssql_db_name'=>'ETMCDB',
      'mssql_db_user'=>'Hotel_User',
      'mssql_db_password'=>'Hotel_User'
      );
     * @param array $con
     * @param boolean $pconnect
     */

    function __construct($con = array(), $pconnect = false, $master = false) {
        $this->_sp_msg = '';
        $this->dbhost = $con['mssql_db_host'];
        $this->dbuser = $con['mssql_db_user'];
        $this->dbpwd = $con['mssql_db_password'];
        $this->dbname = $con['mssql_db_name'];
        $this->pconnect = $pconnect;
        $this->connect($master);
    }

    function __destruct() {
        
    }

    /**
     * 数据库连接
     *
     * @return obj
     */
    function connect($master = false) {
        if ($master) {
            if (empty(self::$_master_handle) || empty(self::$_master_dbname)) {
                $func = $this->pconnect == 1 ? 'mssql_pconnect' : 'mssql_connect';
                if (!self::$_master_handle = @$func($this->dbhost, $this->dbuser, $this->dbpwd)) {
                    $this->halt('无法连接mssql主库');
                }
                self::$_master_dbname = $this->dbname;
            }
            $this->t_handle = self::$_master_handle;
            $this->query('SET ANSI_WARNINGS,ANSI_PADDING,CONCAT_NULL_YIELDS_NULL,ANSI_NULL_DFLT_ON ON');
            
            if (self::$_master_dbname) {
                if (!$this->select_db(self::$_master_dbname)) {
                    $this->halt('无法打开表 ' . self::$_master_dbname);
                }
            } else {
                $this->halt('未选择数据表');
            }
            
        } else {
            if (empty(self::$_handle) || empty(self::$_dbname)) {
                $func = $this->pconnect == 1 ? 'mssql_pconnect' : 'mssql_connect';
                if (!self::$_handle = @$func($this->dbhost, $this->dbuser, $this->dbpwd)) {
                    $this->halt('无法连接mssql');
                }
                self::$_dbname = $this->dbname;
            }
            $this->t_handle = self::$_handle;
            $this->query('SET ANSI_WARNINGS,ANSI_PADDING,CONCAT_NULL_YIELDS_NULL,ANSI_NULL_DFLT_ON ON');

            if (self::$_dbname) {
                if (!$this->select_db(self::$_dbname)) {
                    $this->halt('无法打开表 ' . self::$_dbname);
                }
            } else {
                $this->halt('未选择表');
            }
        }
    }

    /**
     * 选择数据库
     *
     * @param str $dbname
     * @return boolean
     */
    function select_db($dbname) {
        return mssql_select_db($dbname, $this->t_handle);
    }

    /**
     * 执行一条sql指令，select时不能使用limit，mssql分页请用ROW_NUMBER()
     *
     * @param str $sql
     * @return resource 
     */
    function query($sql) {
        if (preg_match("/^insert into/i", $sql)) {
            $sql = "$sql; SELECT @@identity as insertid";
            $query = mssql_query($sql, $this->t_handle) or $this->halt('MsSQL Query 错误', $sql);
            $insid = $this->fetch_row($query);
            $this->insertid = $insid[0];
            return $query;
        } else {
            $query = mssql_query($sql, $this->t_handle) or $this->halt('MsSQL Query 错误', $sql);
            return $query;
        }
    }

    /**
     * 初始化存储过程
     *
     * @param str $sp_name 存储过程名称
     * @return resource
     */
    function init($sp_name) {
        $this->_sp_msg .= 'sp_name：' . $sp_name . '<br>';
        $init = mssql_init($sp_name, $this->t_handle) or $this->halt('MsSQL init 错误' . $this->_sp_msg, $sp_name);
        return $init;
    }

    /**
     * 向存储过程发送一个参数
     *
     * @param resource $stmt mssql_init()返回的句柄
     * @param str $param_name
     * @param mixed $var
     * @param int $type one of SQLTEXT, SQLVARCHAR, SQLCHAR, SQLINT1, SQLINT2, SQLINT4, SQLBIT, SQLFLT4, SQLFLT8, SQLFLTN
     * @param boolean $is_output
     * @param boolean $is_null
     * @param int $maxlen
     * @return boolean 
     */
    function bind($stmt, $param_name, $var, $type, $is_output = false, $is_null = false, $maxlen = -1) {
        if (is_resource($stmt)) {
            $this->_sp_msg .= 'bind： param:' . $param_name . ' value:' . $var . ' type:' . $type . '<br>';
            $bind = mssql_bind($stmt, $param_name, $var, $type, $is_output, $is_null, $maxlen) or $this->halt('MsSQL bind 错误' . $this->_sp_msg, $param_name . $var . $type);
            return $bind;
        }
    }

    /**
     * 执行一个存储过程
     *
     * @param resource $stmt mssql_init()返回的句柄
     * @param boolean $skip_results
     * @return 
     */
    function execute($stmt, $skip_results = false) {
        if (is_resource($stmt)) {
            $exec = mssql_execute($stmt, $skip_results) or $this->halt('MsSQL execute 错误：' . $this->_sp_msg);

            //$exec = mssql_execute($stmt,$skip_results);
            //if (!$exec) {
            //	$this->halt('MsSQL execute 错误'); 
            //}
            return $exec;
        }
    }

    /**
     * 释放执行存储过程占用的内存
     *
     * @param resource $stmt mssql_init()返回的句柄
     */
    function free_statement($stmt) {
        if (is_resource($stmt))
            mssql_free_statement($stmt);
    }

    /**
     * 移动一个内部指针到下一下记录
     *
     * @param resource $query
     */
    function next_result($query) {
        if (is_resource($query))
            mssql_next_result($query);
    }

    /**
     * 直接返回单条记录
     *
     * @param str $sql
     * @return array
     */
    function get_one($sql) {
        $query = $this->query($sql);
        $rs = $this->fetch_array($query);
        $this->free_result($query);
        return $rs;
    }

    /**
     * 返回结果记录
     *
     * @param resource $query
     * @param str $type
     * @return array
     */
    function fetch_array($query, $type = MSSQL_ASSOC) {
        if (is_resource($query))
            return mssql_fetch_array($query, $type);
        return array();
    }

    /**
     * 返回最后一次操作影响的记录数 
     *
     * @return int
     */
    function affected_rows() {
        return mssql_rows_affected($this->t_handle);
    }

    /**
     * 返回select查询返回的记录数
     *
     * @param unknown_type $query
     * @return int
     */
    function num_rows($query) {
        return mssql_num_rows($query);
    }

    /**
     * 返回结果字段数
     *
     * @param resource $query
     * @return int
     */
    function num_fields($query) {
        return mssql_num_fields($query);
    }

    /**
     * 返回结果数据
     *
     * @param resource $query
     * @param int $row
     * @return str 字段值 
     */
    function result($query, $row) {
        return @mssql_result($query, $row);
    }

    /**
     * 释放资源
     *
     * @param resource $query
     * @return boolean
     */
    function free_result($query) {
        if (is_resource($query))
            mssql_free_result($query);
    }

    /**
     * 返回新插入记录的id
     *
     * @return int
     */
    function insert_id() {
        return $this->insertid;
    }

    function fetch_row($query) {
        return mssql_fetch_row($query);
    }

    function close() {
        return mssql_close($this->t_handle);
    }

    function error() {
        return mssql_get_last_message();
        //return TRUE;
    }

    function errno() {
        return TRUE;
    }

    function halt($message = '', $sql = '') {
        $e_msg = $this->dbhost . "<br>MsSQL Query:$sql <br> MsSQL Error:" . $this->error() . " <br> MsSQL Errno:" . $this->errno() . " <br> Message:$message";
        throw new DB_Exception($e_msg);
        //if (function_exists('ms_email')) {
        //require_once(APP_PATH."modules/hotel/common/query.common.php");
        //ms_email($e_msg,$subject = $this->dbhost.'--mssql_error');
        //}
        //exit($e_msg);
    }

}

/**
 * 
 * 
  SELECT * FROM (
  SELECT ROW_NUMBER() OVER(ORDER BY hotelid asc) AS rownum,
 * FROM hotel 
  ) AS hotel
  WHERE rownum BETWEEN 10 AND 100
  ORDER BY hotelid asc

 * */
?>